import datetime
import json
import time
from math import ceil

from fastapi import APIRouter
from re_common.baselibrary.utils.basetime import BaseTime
from re_common.baselibrary.utils.core.requests_core import MsgCode

from apps.allsubdb.wanfangjournal.models import SaveAZListModel, SaveRefModel, SaveRefMongoModel, SaveClassCodeModel, \
    SaveClassLitteCodeModel, WFQKInfoModel, SaveYearModel, SaveIssueModel
from apps.core.global_model import IdModel, SaveJournalIdModel
from apps.core.m_route import ContextIncludedRoute
from apps.core.return_info import InputInfoModel, ReturnInfo, SaveStepMongoModel, SUCCESS, FAILED
from apps.sql_app.mmongodb import MongoDBClient, Coll

router = APIRouter(route_class=ContextIncludedRoute)


@router.post("/step1_a_z/saveqklist")
async def down_wanfangqklist(input: InputInfoModel[SaveAZListModel]):
    return_info = ReturnInfo()
    product = "WANFANG"
    types = "3"
    step_name = "azjournallist"
    pages = input.data.page
    ch = input.data.ch
    html = input.data.html
    ids = "_".join([product, types, step_name, ch, pages])
    # step_info = MongoDBClient.db30_1.client.htmljson.step_info
    step_info = Coll.get_step_info()
    cjip = await step_info.find_one({"_id": ids})
    if cjip:
        dicts = SaveStepMongoModel[SaveAZListModel](step_info=SaveAZListModel()).parse_obj(cjip).dict()
        dicts["step_info"]["html"] = html
        dicts["update_time"] = str(datetime.datetime.now())
        save = SaveStepMongoModel[SaveAZListModel](step_info=SaveAZListModel()).parse_obj(dicts)
        result = await step_info.replace_one({'_id': ids}, save.dict(by_alias=True, exclude={"id"}))
    else:
        save = SaveStepMongoModel[SaveAZListModel](_id=ids, product=product, types=types,
                                                   step_name=step_name,
                                                   step_info=SaveAZListModel(page=pages, ch=ch, html=html),
                                                   update_time=str(datetime.datetime.now()),
                                                   create_time=str(datetime.datetime.now())
                                                   )
        result = await step_info.insert_one(save.dict(by_alias=True))
    return_info.status = SUCCESS
    return_info.msg_code = 200
    return_info.msg = "保存到mongodb成功"
    return_info.data = ""
    return return_info.todict()


@router.post("/step1_classcode/saveqklist")
async def down_wanfangqklist(input: InputInfoModel[SaveAZListModel]):
    return_info = ReturnInfo()
    product = "WANFANG"
    types = "3"
    step_name = "classcodejournallist"
    pages = input.data.page
    classcode = input.data.ch
    html = input.data.html
    ids = "_".join([product, types, step_name, classcode, pages])
    # step_info = MongoDBClient.db30_1.client.htmljson.step_info
    step_info = Coll.get_step_info()
    cjip = await step_info.find_one({"_id": ids})
    if cjip:
        dicts = SaveStepMongoModel[SaveAZListModel](step_info=SaveAZListModel()).parse_obj(cjip).dict()
        dicts["step_info"]["html"] = html
        dicts["update_time"] = str(datetime.datetime.now())
        save = SaveStepMongoModel[SaveAZListModel](step_info=SaveAZListModel()).parse_obj(dicts)
        result = await step_info.replace_one({'_id': ids}, save.dict(by_alias=True, exclude={"id"}))
    else:
        save = SaveStepMongoModel[SaveAZListModel](_id=ids, product=product, types=types,
                                                   step_name=step_name,
                                                   step_info=SaveAZListModel(page=pages, ch=classcode, html=html),
                                                   update_time=str(datetime.datetime.now()),
                                                   create_time=str(datetime.datetime.now())
                                                   )
        result = await step_info.insert_one(save.dict(by_alias=True))
    return_info.status = SUCCESS
    return_info.msg_code = 200
    return_info.msg = "保存到mongodb成功"
    return_info.data = ""
    return return_info.todict()


@router.post("/step1_class/select_html")
async def down_wanfangqklist(input: InputInfoModel[IdModel]):
    """
    最大的分类保存
    :param input:
    :return:
    """
    return_info = ReturnInfo()
    ids = input.data.id
    # step_info = MongoDBClient.db30_1.client.htmljson.step_info
    step_info = Coll.get_step_info()
    cjip = await step_info.find_one({"_id": ids})
    if cjip:
        html = cjip["step_info"]["html"]
    else:
        html = ""
    return_info.status = SUCCESS
    return_info.msg_code = 200
    return_info.msg = "保存到mongodb成功"
    return_info.data = html
    return return_info.todict()


@router.post("/step1_class/classcode")
async def down_wanfangqklist(input: InputInfoModel[SaveClassCodeModel]):
    """
    最大的分类保存
    :param input:
    :return:
    """
    return_info = ReturnInfo()
    product = "WANFANG"
    types = "3"
    step_name = "classcode"
    html = input.data.html
    ids = "_".join([product, types, step_name])
    # step_info = MongoDBClient.db30_1.client.htmljson.step_info
    step_info = Coll.get_step_info()
    cjip = await step_info.find_one({"_id": ids})
    if cjip:
        dicts = SaveStepMongoModel[SaveClassCodeModel](step_info=SaveClassCodeModel()).parse_obj(cjip).dict()
        dicts["step_info"]["html"] = html
        dicts["update_time"] = str(datetime.datetime.now())
        save = SaveStepMongoModel[SaveClassCodeModel](step_info=SaveClassCodeModel()).parse_obj(dicts)
        result = await step_info.replace_one({'_id': ids}, save.dict(by_alias=True, exclude={"id"}))
    else:
        save = SaveStepMongoModel[SaveAZListModel](_id=ids, product=product, types=types,
                                                   step_name=step_name,
                                                   step_info=SaveClassCodeModel(html=html),
                                                   update_time=str(datetime.datetime.now()),
                                                   create_time=str(datetime.datetime.now())
                                                   )
        result = await step_info.insert_one(save.dict(by_alias=True))
    return_info.status = SUCCESS
    return_info.msg_code = 200
    return_info.msg = "保存到mongodb成功"
    return_info.data = ""
    return return_info.todict()


@router.post("/step1_class/classlittecode")
async def down_wanfangqklist(input: InputInfoModel[SaveClassLitteCodeModel]):
    """
    最大的分类保存
    :param input:
    :return:
    """
    return_info = ReturnInfo()
    product = "WANFANG"
    types = "3"
    step_name = "classlittecode"
    html = input.data.html
    id_code = input.data.id_code
    ids = "_".join([product, types, step_name, id_code])
    # step_info = MongoDBClient.db30_1.client.htmljson.step_info
    step_info = Coll.get_step_info()
    cjip = await step_info.find_one({"_id": ids})
    if cjip:
        dicts = SaveStepMongoModel[SaveClassLitteCodeModel](step_info=SaveClassLitteCodeModel()).parse_obj(cjip).dict()
        dicts["step_info"]["html"] = html
        dicts["step_info"]["id_code"] = id_code
        dicts["update_time"] = str(datetime.datetime.now())
        save = SaveStepMongoModel[SaveClassLitteCodeModel](step_info=SaveClassLitteCodeModel()).parse_obj(dicts)
        result = await step_info.replace_one({'_id': ids}, save.dict(by_alias=True, exclude={"id"}))
    else:
        save = SaveStepMongoModel[SaveClassLitteCodeModel](_id=ids, product=product, types=types,
                                                           step_name=step_name,
                                                           step_info=SaveClassLitteCodeModel(html=html,
                                                                                             id_code=id_code),
                                                           update_time=str(datetime.datetime.now()),
                                                           create_time=str(datetime.datetime.now())
                                                           )
        result = await step_info.insert_one(save.dict(by_alias=True))
    return_info.status = SUCCESS
    return_info.msg_code = 200
    return_info.msg = "保存到mongodb成功"
    return_info.data = ""
    return return_info.todict()


@router.post("/step1_a_z/select_az_qklist")
async def down_wanfangqklist():
    return_info = ReturnInfo()
    product = "WANFANG"
    types = "3"
    step_name1 = "azjournallist"
    step_name2 = "classcode"
    step_name3 = "classlittecode"
    step_name4 = "classcodejournallist"
    # step_info = MongoDBClient.db30_1.client.htmljson.step_info
    step_info = Coll.get_step_info()
    dicts = {}
    list = []
    litte_code_list = []
    litte_code_dicts = {}
    classcode = ""
    dicts_class_code_html = {}
    dicts_class_litte_code = {}
    update_time_s = str(BaseTime().get_day_before(datetime.datetime.now(), 3))
    find_dicts = {"product": product, "types": types,
                  "step_name": step_name1, "update_time": {"$gt": update_time_s}}
    async for document in step_info.find(find_dicts):
        page = document["step_info"]["page"]
        ch = document["step_info"]["ch"]
        list.append(str(ch) + "_" + str(page))
        try:
            total = json.loads(document["step_info"]["html"])["total"]
            dicts[ch] = int(total)
        except:
            # 请在这里报告异常
            pass
    async for document in step_info.find(
            {"product": product, "types": types,
             "step_name": step_name2, "update_time": {"$gt": update_time_s}}):
        # update_time = document["update_time"]
        # timeArray = time.strptime(update_time, "%Y-%m-%d %H:%M:%S.%f")
        # timeStamp = int(time.mktime(timeArray))
        # if (time.time() - timeStamp) / 3600 / 24 > 3:
        #     continue
        html = document["step_info"]["html"]
        classcode = html
    async for document in step_info.find(
            {"product": product, "types": types,
             "step_name": step_name3, "update_time": {"$gt": update_time_s}}):
        # update_time = document["update_time"]
        # timeArray = time.strptime(update_time, "%Y-%m-%d %H:%M:%S.%f")
        # timeStamp = int(time.mktime(timeArray))
        # if (time.time() - timeStamp) / 3600 / 24 > 3:
        #     continue
        html = document["step_info"]["html"]
        id_code = document["step_info"]["id_code"]
        dicts_class_code_html[id_code] = html
        for item in json.loads(html)["clusterField"]["ClassCode"]["cluster"]:
            dicts_class_litte_code[item["name"]] = item["number"]

    async for document in step_info.find(
            {"product": product, "types": types,
             "step_name": step_name4, "update_time": {"$gt": update_time_s}}):
        # update_time = document["update_time"]
        # timeArray = time.strptime(update_time, "%Y-%m-%d %H:%M:%S.%f")
        # timeStamp = int(time.mktime(timeArray))
        # if (time.time() - timeStamp) / 3600 / 24 > 3:
        #     continue
        page = document["step_info"]["page"]
        ch = document["step_info"]["ch"]
        litte_code_list.append(str(ch) + "_" + str(page))
        try:
            total = json.loads(document["step_info"]["html"])["total"]
            litte_code_dicts[ch] = int(total)
        except:
            # 请在这里报告异常
            pass

    return_info.status = SUCCESS
    return_info.msg_code = 200
    return_info.msg = "保存到mongodb成功"
    return_info.data = {"dicts": dicts, "list": list, "classcode": classcode, "codehtml": dicts_class_code_html,
                        "littecode": dicts_class_litte_code, "littepage": litte_code_list,
                        "litte_page_dicts": litte_code_dicts}
    return return_info.todict()


@router.post("/step2/saveqkinfo")
async def down_wanfangqklist(input: InputInfoModel[WFQKInfoModel]):
    return_info = ReturnInfo()
    product = "WANFANG"
    types = "3"
    step_name = "qkinfo"
    information = input.data.information
    synopsis = input.data.synopsis
    pykm = input.data.pykm
    ids = "_".join([product, types, step_name, pykm])
    # step_info = MongoDBClient.db30_1.client.htmljson.step_info
    step_info = Coll.get_step_info()
    cjip = await step_info.find_one({"_id": ids})
    if cjip:
        dicts = SaveStepMongoModel[WFQKInfoModel](step_info=WFQKInfoModel()).parse_obj(cjip).dict()
        dicts["step_info"]["information"] = information
        dicts["step_info"]["synopsis"] = synopsis
        dicts["update_time"] = str(datetime.datetime.now())
        save = SaveStepMongoModel[WFQKInfoModel](step_info=WFQKInfoModel()).parse_obj(dicts)
        result = await step_info.replace_one({'_id': ids}, save.dict(by_alias=True, exclude={"id"}))
    else:
        save = SaveStepMongoModel[WFQKInfoModel](_id=ids, product=product, types=types,
                                                 step_name=step_name,
                                                 step_info=WFQKInfoModel(pykm=pykm,
                                                                         information=information,
                                                                         synopsis=synopsis),
                                                 update_time=str(datetime.datetime.now()),
                                                 create_time=str(datetime.datetime.now())
                                                 )
        result = await step_info.insert_one(save.dict(by_alias=True))
    return_info.status = SUCCESS
    return_info.msg_code = 200
    return_info.msg = "保存到mongodb成功"
    return_info.data = ""
    return return_info.todict()


@router.post("/step2/select_qkinfo")
async def down_wanfangqklist(input: InputInfoModel[IdModel]):
    return_info = ReturnInfo()
    product = "WANFANG"
    types = "3"
    step_name = "qkinfo"
    pykm = input.data.id
    ids = "_".join([product, types, step_name, pykm])
    # step_info = MongoDBClient.db30_1.client.htmljson.step_info
    step_info = Coll.get_step_info()
    cjip = await step_info.find_one({"_id": ids})
    if cjip:
        return_info.status = SUCCESS
        return_info.msg_code = 200
        return_info.msg = "查询成功"
        return_info.data = cjip["step_info"]
    else:
        return_info.status = FAILED
        return_info.msg_code = MsgCode.MONGO_NO_ID
        return_info.msg = "没有该数据"
        return_info.data = ""

    return return_info.todict()


@router.post("/step5/save_yearlist")
async def down_wanfangqklist(input: InputInfoModel[SaveYearModel]):
    return_info = ReturnInfo()
    product = "WANFANG"
    types = "3"
    step_name = "yearlist"
    pykm = input.data.pykm
    html = input.data.html
    ids = "_".join([product, types, step_name, pykm])
    # step_info = MongoDBClient.db30_1.client.htmljson.step_info
    step_info = Coll.get_step_info()
    cjip = await step_info.find_one({"_id": ids})
    if cjip:
        dicts = SaveStepMongoModel[SaveYearModel].parse_obj(cjip).dict()
        dicts["step_info"]["html"] = html
        dicts["step_info"]["pykm"] = pykm
        dicts["update_time"] = str(datetime.datetime.now())
        save = SaveStepMongoModel[SaveYearModel].parse_obj(dicts)
        result = await step_info.replace_one({'_id': ids}, save.dict(by_alias=True, exclude={"id"}))
    else:
        save = SaveStepMongoModel[SaveYearModel](_id=ids, product=product, types=types,
                                                 step_name=step_name,
                                                 step_info=SaveYearModel(pykm=pykm, html=html),
                                                 update_time=str(datetime.datetime.now()),
                                                 create_time=str(datetime.datetime.now())
                                                 )
        result = await step_info.insert_one(save.dict(by_alias=True))

    return_info.status = SUCCESS
    return_info.msg_code = 200
    return_info.msg = "保存到mongodb成功"
    return_info.data = ""
    return return_info.todict()


@router.post("/step5/select_yearlist")
async def down_wanfangqklist():
    return_info = ReturnInfo()
    product = "WANFANG"
    types = "3"
    step_name = "yearlist"
    # step_info = MongoDBClient.db30_1.client.htmljson.step_info
    step_info = Coll.get_step_info()
    list = []
    update_time_s = str(BaseTime().get_day_before(datetime.datetime.now(), 3))
    async for document in step_info.find(
            {"product": product, "types": types,
             "step_name": step_name, "update_time": {"$gt": update_time_s}}):  # 查询所有文档
        # update_time = document["update_time"]
        # timeArray = time.strptime(update_time, "%Y-%m-%d %H:%M:%S.%f")
        # timeStamp = int(time.mktime(timeArray))
        # if (time.time() - timeStamp) / 3600 / 24 > 3:
        #     continue
        pykm = document["step_info"]["pykm"]
        list.append(pykm)
    return_info.status = SUCCESS
    return_info.msg_code = 200
    return_info.msg = "保存到mongodb成功"
    return_info.data = list
    return return_info.todict()


@router.post("/step7/issue_info")
async def journal_list(input: InputInfoModel[SaveIssueModel]):
    """
    保存到大表
    :param input:
    :return:
    """
    return_info = ReturnInfo()
    product = "WANFANG"
    types = "3"
    step_name = "issueinfo"
    pykm = input.data.pykm
    pubyear = input.data.pubyear
    num = input.data.num
    pageIdx = input.data.page
    html = input.data.html
    ids = "_".join([product, types, step_name, pykm, pubyear, num, pageIdx])
    # step_info = MongoDBClient.db30_1.client.htmljson.step_info
    step_info = Coll.get_step_info()

    cjip = await step_info.find_one({"_id": ids})
    if cjip:
        dicts = SaveStepMongoModel[SaveIssueModel].parse_obj(cjip).dict()
        dicts["step_info"]["html"] = html
        dicts["step_info"]["pykm"] = pykm
        dicts["step_info"]["pubyear"] = pubyear
        dicts["step_info"]["num"] = num
        dicts["step_info"]["page"] = str(pageIdx)
        dicts["update_time"] = str(datetime.datetime.now())
        save = SaveStepMongoModel[SaveIssueModel].parse_obj(dicts)
        result = await step_info.replace_one(
            {'_id': ids}, save.dict(by_alias=True, exclude={"id"}))
    else:
        save = SaveStepMongoModel[SaveIssueModel](
            _id=ids, product=product, types=types,
            step_name=step_name,
            step_info=SaveIssueModel(pykm=pykm, html=html,
                                     pubyear=pubyear,
                                     num=num, page=str(pageIdx)),
            update_time=str(datetime.datetime.now()),
            create_time=str(datetime.datetime.now())
        )
        result = await step_info.insert_one(save.dict(by_alias=True))
    return_info.status = SUCCESS
    return_info.msg_code = 200
    return_info.msg = "保存到mongodb成功"
    return_info.data = ""
    return return_info.todict()


@router.post("/step_control/step")
async def down_wanfangqklist(input: InputInfoModel[str]):
    return_info = ReturnInfo()
    product = "WANFANG"
    types = "3"
    step_name = "azjournallist"
    # step_name = input.data.step_name
    # jsons = input.data.jsons
    # ids = "_".join([product, types, step_name, ch, pages])
    # step_info = MongoDBClient.db30_1.client.htmljson.step_info
    step_info = Coll.get_step_info()
    cjip = await step_info.find_one({"product": product, "types": types, "step_name": step_name})
    if cjip is None:
        ids = "1"
        ids = "_".join([product, types, step_name, ids])
    else:
        pass

    return return_info.todict()


@router.post("/step9/save_ref")
async def save_ref(input: InputInfoModel[SaveRefModel]):
    """
    添加和更新ref
    :param input:
    :return:
    """
    return_info = ReturnInfo()
    rawid = input.data.Id
    page = input.data.page
    count = input.data.count
    html = input.data.html
    # ref_info = MongoDBClient.db30_1.client.htmljson.wanfang_ref
    ref_info = Coll.get_wanfang_ref()
    cjip = await ref_info.find_one({"_id": rawid})
    if cjip:
        dicts = SaveRefMongoModel().parse_obj(cjip).dict()
        if dicts["count"] != count:
            dicts["count"] = count
            dict_page = {}
            for i in range(1, ceil(int(count) / 10) + 1):
                dict_page[str(i)] = ""
            dict_page[page] = html
            dicts["page_info"] = dict_page
        else:
            dicts["page_info"][page] = html
        dicts["update_time"] = str(datetime.datetime.now())
        save = SaveRefMongoModel().parse_obj(dicts)
        result = await ref_info.replace_one({'_id': rawid}, save.dict(by_alias=True, exclude={"id"}))
    else:
        dict_page = {}
        for i in range(1, ceil(int(count) / 10) + 1):
            dict_page[str(i)] = ""
        dict_page[page] = html
        save = SaveRefMongoModel(_id=rawid,
                                 count=count,
                                 page_info=dict_page,
                                 befor_times={},
                                 update_time=str(datetime.datetime.now()),
                                 create_time=str(datetime.datetime.now())
                                 )
        result = await ref_info.insert_one(save.dict(by_alias=True))
    return_info.status = SUCCESS
    return_info.msg_code = 200
    return_info.msg = "保存到mongodb成功"
    return_info.data = ""
    return return_info.todict()


@router.post("/verification/ver_ref")
async def ver_ref(input: InputInfoModel[str]):
    """
    验证ref是否下载完
    :param input:
    :return:
    """
    return_info = ReturnInfo()
    return_info.status = SUCCESS
    return_info.msg_code = 200
    return_info.msg = ""

    rawid = input.data
    # ref_info = MongoDBClient.db30_1.client.htmljson.wanfang_ref
    ref_info = Coll.get_wanfang_ref()
    cjip = await ref_info.find_one({"_id": rawid})
    dict_result = {}
    if cjip:
        dicts = SaveRefMongoModel().parse_obj(cjip).dict()

        if dicts["befor_times"]:
            if dicts["befor_times"]["update_time"] == dicts["update_time"]:
                dict_result["bools"] = "false"
                dict_result["is_have"] = "false"
                dict_result["total"] = ""
                dict_result["lists_page"] = []

                return_info.data = dict_result
                return return_info.todict()

        page_info = dicts["page_info"]
        lists_page = []
        bool = "true"
        for k, v in page_info.items():
            if v == "":
                bool = "false"
            else:
                lists_page.append(k)
        dict_result["bools"] = bool
        dict_result["total"] = dicts["count"]
        dict_result["is_have"] = "true"
        dict_result["lists_page"] = lists_page
    else:
        dict_result["bools"] = "false"
        dict_result["is_have"] = "false"
        dict_result["total"] = ""
        dict_result["lists_page"] = []

    return_info.data = dict_result
    return return_info.todict()


@router.post("/back/back_ref")
async def back_ref(input: InputInfoModel[str]):
    """
    将原来的数据放入back字段
    :param input:
    :return:
    """
    return_info = ReturnInfo()
    rawid = input.data
    # ref_info = MongoDBClient.db30_1.client.htmljson.wanfang_ref
    ref_info = Coll.get_wanfang_ref()
    cjip = await ref_info.find_one({"_id": rawid})
    if cjip:
        dicts = SaveRefMongoModel().parse_obj(cjip).dict()
        del dicts["id"]
        del dicts["befor_times"]
        if dicts["page_info"] != {} or dicts["count"] != "":
            dicts_save = SaveRefMongoModel().parse_obj(cjip).dict()
            dicts_save["befor_times"] = dicts
            save = SaveRefMongoModel().parse_obj(dicts_save)
            result = await ref_info.replace_one({'_id': rawid}, save.dict(by_alias=True, exclude={"id"}))
    return_info.status = SUCCESS
    return_info.msg_code = 200
    return_info.msg = ""
    return_info.data = ""
    return return_info.todict()
